#include "RR.h"
#include <stdio.h>
#include <stdlib.h>

/**
 * 函数: calculateTimes
 * 功能: 根据时间片轮转调度算法计算每个进程的完成时间、周转时间和等待时间
 *
 * 参数:
 *  - processes: 指向包含多个进程信息的数组
 *  - n: 进程数量
 *  - time_slice: 时间片长度
 *
 * 描述:
 *  计算进程的完成时间，周转时间和等待时间并存在结构体中即可
 */

struct ready_queue
{
  Process *PCB;
  struct ready_queue *next;
};

int time = 0;

void
calculateTimes (Process *processes, int n, int time_slice)
{
  // TODO
  struct ready_queue *dummy=malloc (sizeof (struct ready_queue));
  dummy->next = NULL;
  dummy->PCB = NULL;
  struct ready_queue *head = dummy;
  struct ready_queue *tail = dummy;

  int *in_queue=malloc (sizeof (int) * n);
  for (int i = 0; i < n; i++)
    {
      in_queue[i] = 0;
    }
  int in_queue_count = 0;
  
  while(1)
  {
    //首先查看是否有任务到达
    if(in_queue_count<n)
    {
      for(int i=0;i<n;i++)
      {
        if(in_queue[i]==0&&processes[i].arrival_time<=time)//入队
        {
          struct ready_queue *new_node = malloc (sizeof (struct ready_queue));
          new_node->PCB = &processes[i];
          new_node->next = NULL;
          tail->next = new_node;
          tail = new_node;
          in_queue[i]=1;
          in_queue_count++;
        }
      }
    }

    if(head->next==NULL)//队列为空
    {
      time++;
      continue;
    }
    //出队
    struct ready_queue *temp = head->next;
    head->next = head->next->next;
    temp->next = NULL;
    if(head->next==NULL)
    {
      tail = head;
    }

    //处理
    if(temp->PCB->remaining_time>time_slice)//单个时间片内完成不了
    {
      //模拟时间的流逝,流逝一个时间片
      for(int i=0;i<time_slice;i++)
      {
        time++;
        //查看是否有任务到达
        for(int i=0;i<n;i++)
       {
        if(in_queue[i]==0&&processes[i].arrival_time<=time)//入队
        {
          struct ready_queue *new_node = malloc (sizeof (struct ready_queue));
          new_node->PCB = &processes[i];
          new_node->next = NULL;
          tail->next = new_node;
          tail = new_node;
          in_queue[i]=1;
          in_queue_count++;
        }
       }
      }
      temp->PCB->remaining_time-=time_slice;
      // 重新入队
      if (head->next == NULL) {
        head->next = temp;
        tail = temp;
      } else {
        tail->next = temp;
        tail = temp;
      }
    }
    else//该时间片内完成
    {
      //模拟时间的流逝,流逝剩余时间
      for(int i=0;i<temp->PCB->remaining_time;i++)
      {
        time++;
        //查看是否有任务到达
        for(int i=0;i<n;i++)
        {
          if(in_queue[i]==0&&processes[i].arrival_time<=time)//入队
          {
            struct ready_queue *new_node = malloc (sizeof (struct ready_queue));
            new_node->PCB = &processes[i];
            new_node->next = NULL;
            tail->next = new_node;
            tail = new_node;
            in_queue[i]=1;
            in_queue_count++;
          }
        }
      }
      temp->PCB->remaining_time=0;
      temp->PCB->completion_time=time;
      temp->PCB->turnaround_time=temp->PCB->completion_time-temp->PCB->arrival_time;
      temp->PCB->waiting_time=temp->PCB->turnaround_time-temp->PCB->burst_time;
      free(temp);
    }

    if(head->next==NULL&&in_queue_count==n)//所有进程都完成了
    {
      break;
    }

  }
  free(dummy);
  free(in_queue);

  return;
}
